﻿using System.Collections.Generic;

namespace Algorytm
{
    public class Algorytm_Klasa
    {
        public int numer;
        public int preferowana_sala;
        public int liczba_przedmiotow;
        public int laczna_liczba_godzin;
        public List<Algorytm_Zajecia> zajecia;
        public Algorytm_Element_Planu[][] tab;
        private int[] dni = new int[10];

        public Algorytm_Klasa() { }
        public void dodaj_do_planu(Algorytm_Wyniki wyniki)
        {
            for (int i = 0; i < tab.Length; i++)
            {
                for (int j = 0; j < tab[i].Length; j++)
                {
                    if (tab[i][j].Czy_jest())
                    {
                        wyniki.dodaj_element(numer, tab[i][j].nauczyciel, tab[i][j].przedmiot, tab[i][j].sala,
                            i, j, tab[i][j].dlugosc, tab[i][j].czy_grupowe);
                        if (tab[i][j].czy_jest_drugi_przedmiot)
                        {
                            wyniki.dodaj_element(numer, tab[i][j].drugi_przedmiot.nauczyciel, tab[i][j].drugi_przedmiot.przedmiot, tab[i][j].drugi_przedmiot.sala,
                            i, j, tab[i][j].drugi_przedmiot.dlugosc, true);
                        }
                    }
                }
            }
        }

        public void dodaj_do_planu_awaryjnego(Algorytm_Wyniki wyniki)
        {
            for (int i = 0; i < tab.Length; i++)
            {
                for (int j = 0; j < tab[i].Length; j++)
                {
                    if (tab[i][j].Czy_jest() && tab[i][j].czy_jest_z_awaryjnego)
                    {
                        wyniki.dodaj_element(numer, tab[i][j].nauczyciel, tab[i][j].przedmiot, tab[i][j].sala,
                            i, j, tab[i][j].dlugosc, tab[i][j].czy_grupowe);
                        if (tab[i][j].czy_jest_drugi_przedmiot)
                        {
                            wyniki.dodaj_element(numer, tab[i][j].drugi_przedmiot.nauczyciel, tab[i][j].drugi_przedmiot.przedmiot, tab[i][j].drugi_przedmiot.sala,
                            i, j, tab[i][j].drugi_przedmiot.dlugosc, true);
                        }
                    }
                }
            }
        }

        public void Print()
        {
            for (int i = 0; i < tab.Length; i++)
            {
                for (int j = 0; j < tab[i].Length; j++)
                {
                    tab[i][j].Print();
                }
            }
        }

        public bool Czy_jest_miejsce_na_zajecia_grupowe(int dzien, int godzina)
        {
            if (tab[dzien][godzina].czy_grupowe)
            {
                return !tab[dzien][godzina].czy_jest_drugi_przedmiot;
            }
            return true;
        }

        public bool Czy_zajecia_sa_grupowe(int numer_zajec)
        {
            bool czy = false;
            foreach (var item in zajecia)
            {
                if (item.numer_przedmiotu == numer_zajec)
                    return item.grupy != 1;
            }
            return czy;
        }

        public Algorytm_Klasa(int _numer_klasy, int _numer_preferowanej_sali, int _liczba_przedmiotow, int _laczna_liczba_godzin, Algorytm_Zajecia[] _tablica_zajec)
        {
            Algorytm_Tworzenie_dla_Szkoly.p("tworze konstruktor w klasie");
            for (int i = 0; i < 10; i++) dni[i] = 0;
            tab = Algorytm_Tworzenie_dla_Szkoly.Init_tab();
            numer = _numer_klasy;
            zajecia = new List<Algorytm_Zajecia>();
            preferowana_sala = _numer_preferowanej_sali;
            liczba_przedmiotow = _liczba_przedmiotow;
            laczna_liczba_godzin = _laczna_liczba_godzin;
            for (int i = 0; i < _tablica_zajec.Length; i++)
            {
                zajecia.Add(_tablica_zajec[i]);
            }
        }

        public void Usun_skojarzenie(int dzien, int godzina)
        {
            int numer_zajec = tab[dzien][godzina].przedmiot;
            tab[dzien][godzina].Usun();
            foreach (var item in zajecia)
            {
                if (item.numer_przedmiotu == numer_zajec)
                {
                    item.usun_zajecia(dzien, godzina);
                    dni[dzien]--;
                    return;
                }
            }
        }

        public void Dodaj_skojarzenie_do_planu_awaryjnego(Algorytm_Element_Planu element, int dzien, int godzina)
        {

            if (tab == null) {
                Algorytm_Tworzenie_dla_Szkoly.p("tab is fucking null.");
            }
            Algorytm_Tworzenie_dla_Szkoly.p("wartosci "+dzien+" godzina "+godzina);
            if (tab[dzien] == null) {
                Algorytm_Tworzenie_dla_Szkoly.p("tab[dzien] is fucking null.");
            }
            Algorytm_Tworzenie_dla_Szkoly.p("tab.length="+tab.Length+" ;  tab[dzien].length = " + tab[dzien].Length);
            
            tab[dzien][godzina] = element;
        }

        public void Dodaj_skojarzenie(Algorytm_Element_Planu element, int dzien, int godzina)
        {
            bool czy = tab[dzien][godzina].Czy_jest();
            if (czy)
            {
                Algorytm_Tworzenie_dla_Szkoly.p("własnie dodaje drugie element");
                tab[dzien][godzina].drugi_przedmiot = element;
                tab[dzien][godzina].czy_jest_drugi_przedmiot = true;
            }
            else
                tab[dzien][godzina] = element;
            Algorytm_Tworzenie_dla_Szkoly.p("dodaje skojarzenie w klasie: " + numer + " przedmiot " + element.przedmiot + " nauczyciel "
                + element.nauczyciel + " dzien " + dzien + " godzina " + godzina);
            int numer_zajec = element.przedmiot;
            foreach (var item in zajecia)
            {
                if (item.numer_przedmiotu == numer_zajec)
                {
                    item.dodaj_zajecia(element.nauczyciel, dzien, godzina);
                    if (!czy) dni[dzien]++;
                    return;
                }
            }
        }

        public bool czy_sa_miejsca(int nr_przedmiotu)
        {
            bool czy = false;
            foreach (var item in zajecia)
            {
                if (item.numer_przedmiotu == nr_przedmiotu)
                    return item.czy_sa_miejsca();
            }
            return czy;
        }

        public int numer_prowdzacego_zajecia(int nr_przedmiotu)
        {
            int nr = -1;
            foreach (var item in zajecia)
            {
                if (item.numer_przedmiotu == nr_przedmiotu)
                    return item.numer_prowadzacego;
            }
            return nr;
        }

        public int liczba_zajec_z_przedmiotu(int nr_przedmiotu)
        {
            foreach (var item in zajecia)
            {
                if (item.numer_przedmiotu == nr_przedmiotu)
                    return item.obecna_liczba_godzin;
            }
            return 0;
        }

        public bool czy_moga_byc_zajecia(int dzien, int godzina)
        {
            if (tab[dzien][godzina].klasa == -1) return true;
            else return false;
        }

        public int ilosc_zajec_w_danym_dniu(int dzien, int nr_przedmiotu)
        {
            int pom = 0;
            foreach (var item in zajecia)
            {
                if (item.numer_przedmiotu == nr_przedmiotu)
                {
                    return item.licza_zajec_w_dniu(dzien);
                }
            }
            return pom;
        }

        public int policz_priotytet(int dzien, int godzina)
        {
            int prio = 0;
            if (dni[dzien] == 0) return 6;
            if (godzina > 0)
                if (tab[dzien][godzina - 1].klasa != -1) prio += 2;
            if (godzina + 1 < Algorytm_Tworzenie_dla_Szkoly.liczba_godzin_w_dniu)
                if (tab[dzien][godzina + 1].klasa != -1) prio += 2;
            return prio;
        }

        public int policz_priorytet_usuniecia(int dzien, int godzina)
        {
            int prio = 0;
            if (godzina > 0)
                if (tab[dzien][godzina - 1].klasa != -1) prio -= 2;
            if (godzina + 1 < Algorytm_Tworzenie_dla_Szkoly.liczba_godzin_w_dniu)
            {
                tab[dzien][godzina].Print();

                if (tab[dzien][godzina + 1].klasa != -1) prio -= 2;
            }
            if (prio != -4) return 0;
            return prio;
        }
    }
}